package com.denimgroup.threadfix.service;

import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.denimgroup.threadfix.data.dao.UserDao;
import com.denimgroup.threadfix.data.dao.VulnerabilityCommentDao;
import com.denimgroup.threadfix.data.dao.VulnerabilityDao;
import com.denimgroup.threadfix.data.entities.ThreadFixUserDetails;
import com.denimgroup.threadfix.data.entities.User;
import com.denimgroup.threadfix.data.entities.Vulnerability;
import com.denimgroup.threadfix.data.entities.VulnerabilityComment;

@Service
@Transactional
public class VulnerabilityCommentServiceImpl implements VulnerabilityCommentService {

	private final SanitizedLogger log = new SanitizedLogger(VulnerabilityCommentService.class);
	
	private VulnerabilityCommentDao vulnerabilityCommentDao;
	private VulnerabilityDao vulnerabilityDao;
	private UserDao userDao;
	
	@Autowired
	public VulnerabilityCommentServiceImpl(VulnerabilityDao vulnerabilityDao,
			UserDao userDao,
			VulnerabilityCommentDao vulnerabilityCommentDao) {
		this.vulnerabilityCommentDao = vulnerabilityCommentDao;
		this.vulnerabilityDao = vulnerabilityDao;
		this.userDao = userDao;
	}
	
	@Override
	public List<VulnerabilityComment> loadAllForVuln(Integer vulnId) {
		return vulnerabilityCommentDao.retrieveAllForVuln(vulnId);
	}

	@Override
	public String addCommentToVuln(String commentString, Integer vulnId) {
		
		if (commentString == null || commentString.trim().isEmpty()) {
			log.error("Invalid comment string.");
			return EMPTY;
		}
		
		if (commentString.length() > VulnerabilityComment.COMMENT_LENGTH) {
			log.error("String was too long.");
			return LENGTH;
		}
		
		if (vulnId == null) {
			log.error("Invalid vuln ID");
			return VULN;
		}
		
		Vulnerability vuln = vulnerabilityDao.retrieveById(vulnId);
		
		if (vuln == null) {
			log.error("Invalid vuln ID");
			return VULN;
		}
		
		User user = null;
		
		Object auth = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		if (auth != null && auth instanceof ThreadFixUserDetails) {
			user = userDao.retrieveById(((ThreadFixUserDetails) auth).getUserId());
		}
		
		if (user == null) {
			log.error("Invalid user.");
			return USER;
		}
		
		VulnerabilityComment comment = new VulnerabilityComment();
		comment.setComment(commentString);
		comment.setVulnerability(vuln);
		comment.setTime(new Date());
		comment.setUser(user);
		vulnerabilityCommentDao.saveOrUpdate(comment);
		
		return VALID;
	}
}
